// 工具函数集合，例如时间日期处理、金钱处理等方法统一在此文件编写

// async 方法的处理
export const createCatchAsyncFun = (errorHandle) => {
  return async (fn) => {
    try {
      return [null, await fn];
    } catch (error) {
      typeof errorHandle === "function" && errorHandle(error);
      return [error, null];
    }
  };
};

// 获取两个时刻相隔的毫秒数
// time1: 年/月/日 小时:分钟:秒
// time2: 年/月/日 小时:分钟:秒
export function getMillisecondWith2Time(time1, time2) {
  if (!(time1 instanceof Date)) {
    time1 = new Date(time1);
  }
  if (!(time2 instanceof Date)) {
    time2 = new Date(time2);
  }
  return Math.abs(time1.getTime() - time2.getTime());
}

// 生成一个节流函数，规定在一个单位时间内，只能触发一次函数。如果这个单位时间内触发多次函数，只有一次生效
export function getThrottleFun(method, context, time = 100) {
  var a = function (...avgs) {
    clearTimeout(a.tId);
    a.tId = setTimeout(function () {
      method.apply(context, avgs);
      a.tId = null;
    }, time);
  };
  return a;
}

// 简单的深拷贝，只针对简单对象和Array，且不存在循环引用
export function simpleCloneDeep(value) {
  if (Object.prototype.toString.call(value) === "[object Object]") {
    const obj = {};
    for (let key in value) {
      obj[key] = simpleCloneDeep(value[key]);
    }
    return obj;
  } else if (Array.isArray(value)) {
    const arr = [];
    value.forEach((item, i) => {
      arr[i] = simpleCloneDeep(item);
    });
    return arr;
  } else {
    return value;
  }
}

// 获取一个范围里面的随机整数，包括头尾
export function getRandomWithRange(star, end) {
  return ((star + Math.random() * (end - star + 1)) * 2) >> 1;
}

// 把对象拼接成url字符串
export function object2urlString(obj) {
  if (!obj || typeof obj !== "object") return "";
  let keyValues = [];
  for (let key in obj) {
    keyValues.push(`${key}=${encodeURIComponent(obj[key])}`);
  }
  return keyValues.join("&");
}

// 业务功能：根据商品的
export function getColorAndSize(info) {
  if (!info || !info.initialSku) return "";
  // 获取规格尺寸
  let result = [];
  for (let treeItem of info.sku.tree) {
    const res = treeItem.v.find(
      (item) => item.id === info.initialSku[treeItem.k_s]
    );
    if (res) {
      result.push(res.name);
    }
  }
  return result.join(";");
}

// 按照保留n位小数进行四舍五入
export function MathRoundByByte(num, n = 2) {
  const temp = Math.pow(10, n);
  return Math.round(num * temp) / temp;
}

/**
 * 判断一个字符串是否是一个有效的图片url
 * @param {String} url
 * @return {Boolean}
 */
export function isValidImgUrl(url = "") {
  if (typeof url !== "string") return false;
  return url.includes("http") || url.includes("data:image");
}

// #ifdef H5
// 获取url上的某个参数
export function getQueryString(name, url) {
  if (url && url.indexOf("?") !== -1) {
    var args = new Object(); //声明一个空对象

    //获取URL中全部参数列表数据，第一个？号后面的都是query
    // 修复url上有多个？而被分割多段
    var query = "&" + url.replace(/[^?]*\?/, "");
    if (query.indexOf("#") !== -1) {
      query = query.split("#")[0];
    }
    var pairs = query.split("&"); // 以 & 符分开成数组
    for (var i = 0; i < pairs.length; i++) {
      var pos = pairs[i].indexOf("="); // 查找 "name=value" 对
      if (pos === -1) continue; // 若不成对，则跳出循环继续下一对
      var argname = pairs[i].substring(0, pos); // 取参数名
      var value = pairs[i].substring(pos + 1); // 取参数值
      value = decodeURIComponent(value); // 若需要，则解码
      args[argname] = value; // 存成对象的一个属性
    }
    return args[name];
  } else {
    return null;
  }
}
// 删除url中某个参数
export function fdelParam(url, paramKey) {
  var urlParam = url.split("?")[1]; //页面参数
  var beforeUrl = url.substr(0);
  if (url.includes("?")) {
    beforeUrl = url.substr(0, url.indexOf("?")); //页面主地址（参数之前地址）
  }
  var nextUrl = "";
  var arr = new Array();
  if (urlParam) {
    var urlParamArr = urlParam.split("&"); //将参数按照&符分成数组
    for (var i = 0; i < urlParamArr.length; i++) {
      var paramArr = urlParamArr[i].split("="); //将参数键，值拆开
      //如果键雨要删除的不一致，则加入到参数中
      if (paramArr[0] !== paramKey) {
        arr.push(urlParamArr[i]);
      }
    }
  }
  if (arr.length > 0) {
    nextUrl = "?" + arr.join("&");
  }
  url = beforeUrl + nextUrl;
  return url;
}
// url 获取 img
export function urlToImage(url) {
  return new Promise((resolve, reject) => {
    let image = new Image();
    image.onload = function () {
      resolve(image);
    };
    image.onerror = () => {
      reject(new Error("urlToImage error"));
    };
    image.setAttribute("crossOrigin", "Anonymous");
    image.src = url;
  });
}
// url 转 Base64
export function urlToBase64(url) {
  return new Promise((resolve, reject) => {
    let image = new Image();
    image.onload = function () {
      let canvas = document.createElement("canvas");
      canvas.width = this.naturalWidth;
      canvas.height = this.naturalHeight;
      // 将图片插入画布并开始绘制
      canvas.getContext("2d").drawImage(image, 0, 0);
      // result
      let result = canvas.toDataURL("image/png");
      resolve(result);
    };
    // CORS 策略，会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
    // 后台需要设置允许跨域
    image.setAttribute("crossOrigin", "Anonymous");
    image.src = url;
    // 图片加载失败的错误处理
    image.onerror = () => {
      reject(new Error("urlToBase64 error"));
    };
  });
}

// #endif

// 判断当前环境是否是否是微信
export function isWeixinUtil() {
  // #ifdef H5
  const result = navigator.userAgent.indexOf("MicroMessenger") >= 0;
  return result;
  // #endif
}

// 区别处理H5的sessionStorage和其它端的Storage
export const sessionStorageHack = {
  removeItem(key) {
    /* #ifdef H5 */
    sessionStorage.removeItem(key);
    /* #endif */
    // #ifndef H5
    uni.removeStorageSync(key);
    /* #endif */
  },
  setItem(key, value) {
    /* #ifdef H5 */
    sessionStorage.setItem(key, value); // 留下主动登陆的标识
    /* #endif */
    // #ifndef H5
    uni.setStorageSync(key, value);
    /* #endif */
  },
  getItem(key) {
    let result = "";
    /* #ifdef H5 */
    result = sessionStorage.getItem(key);
    /* #endif */
    // #ifndef H5
    result = uni.getStorageSync(key);
    /* #endif */
    return result;
  },
};
